package com.yu.crm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yu.crm.domain.pojo.PubUserActionLog;
import com.yu.crm.domain.request.LogReq;
import com.yu.crm.domain.request.PubUserActionLogReq;
import com.yu.crm.domain.request.UserActionLogListReq;
import com.yu.crm.domain.response.LogRes;
import com.yu.crm.domain.response.NumberVisitsRes;
import com.yu.crm.mapper.PubUserActionLogMapper;
import com.yu.crm.service.IPubUserActionLogService;
import com.yu.crm.utils.DateUtil;
import com.yu.crm.utils.FileUtil;
import com.yu.crm.utils.PageUtils;
import com.yxzz.common.config.UserCacheManager;
import com.yxzz.common.exception.GeneralException;
import com.yxzz.common.helper.DataHelpers;
import com.yxzz.common.helper.DateHelpers;
import com.yxzz.common.helper.valid.ValidatorHelpers;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;


/**
 * <p>
 * 用户行为记录表 服务实现类
 * </p>
 *
 * @author song
 * @since 2019-11-25
 */
@Service
@Log4j2
@Transactional(rollbackFor = Exception.class)
public class PubUserActionLogService extends ServiceImpl<PubUserActionLogMapper, PubUserActionLog> implements IPubUserActionLogService {

    @Autowired
    private UserCacheManager userCacheManager;

    @Value("${log_file_path}")
    private String filePath;

    /**
     * 用户行为审计保存
     *
     * @param req
     */
    public void saveLog(PubUserActionLogReq req) {
        try {
            PubUserActionLog pubUserActionLog = new PubUserActionLog();
            String userId = userCacheManager.getCurrentUser().getUserId();
            BeanUtils.copyProperties(req, pubUserActionLog);
            pubUserActionLog.setAppId(req.getAppId());
            pubUserActionLog.setUserId(userId);
            pubUserActionLog.setIsDeleted(0);
            pubUserActionLog.setGmtCreate(DateHelpers.now());
            log.info("用户行为审计信息：{}" + pubUserActionLog);
            ValidatorHelpers.validateDataSave(baseMapper.insert(pubUserActionLog));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("用户行为审计信息保存失败:{}"+e.getMessage());
        }
    }

    /**
     * 用户行为审计列表
     *
     * @param req
     * @param page
     */
    public IPage<PubUserActionLog> logList(Page<PubUserActionLog> page, UserActionLogListReq req) {
        QueryWrapper<PubUserActionLog> queryWrapper = new QueryWrapper<>();
        /*if (DataHelpers.isNotEmptyString(req.getStartDate())) {
            queryWrapper.ge("gmt_create", req.getStartDate());
        }
        if (DataHelpers.isNotEmptyString(req.getEndDate())) {
            queryWrapper.le("gmt_create", req.getEndDate());
        }*/
        if (DataHelpers.isNotEmptyString(req.getDate())) {
            queryWrapper.like("pual.gmt_create", req.getDate());
        }
        if (DataHelpers.isNotEmpty(req.getActionType())) {
            queryWrapper.eq("action_type", req.getActionType());
        }

        if (DataHelpers.isNotEmptyString(req.getSerach())) {
            queryWrapper.and(
                    wapper -> wapper.like("cuser.user_name", req.getSerach()).or().
                            like("pai.app_description", req.getSerach()).or().
                            like("pual.action_content", req.getSerach()).or().
                            like("pual.ip", req.getSerach())
            );
        }
        queryWrapper.eq("pual.is_deleted",0);
        queryWrapper.orderByDesc("pual.gmt_create");
        IPage<PubUserActionLog> pubUserActionLogIPage = baseMapper.logList(page, queryWrapper);
        return pubUserActionLogIPage;
    }

    /**
     * 用户行为审计删除
     */
    public void del(String ids) {
        try {
            if (DataHelpers.isNotEmptyString(ids)) {
                String[] split = ids.split(",");
                if (DataHelpers.isNotEmpty(split) && split.length > 0) {
                    List<PubUserActionLog> pubUserActionLogs = baseMapper.selectBatchIds(Arrays.asList(split));
                    if (DataHelpers.isNotEmpty(pubUserActionLogs) && pubUserActionLogs.size() > 0) {
                        for (PubUserActionLog pubUserActionLog : pubUserActionLogs
                        ) {
                            pubUserActionLog.setGmtModified(DateHelpers.now());
                            pubUserActionLog.setIsDeleted(1);
                        }
                        this.updateBatchById(pubUserActionLogs);
                    }
                }
            } else {
                log.info("用户行为审计暂无删除记录，审计ids为空");
            }
        } catch (Exception e) {
            log.error("用户行为审计删除失败：{}" + e.getMessage());
        }
    }

    /**
     * 详情
     * @param id
     */
    public PubUserActionLog detail(String id) {
        PubUserActionLog pubUserActionLog = baseMapper.detail(id);
        log.info("用户行为审计详情：{}" + pubUserActionLog);
        return pubUserActionLog;
    }

    /**
     * 日志文件列表
     * @param page
     * @param req
     * @return
     */
    public IPage<LogRes> appLogList(Page<LogRes> page, LogReq req) {
        String path = filePath;
        Page<LogRes> logResPage = new Page<>();
        List<LogRes> fileNameList = FileUtil.ergodic(path, req);
        Collections.sort(fileNameList, (o1, o2) -> (int) (DateHelpers.localDateTimeToLong(DateHelpers.parseDateTime(o2.getCreateTime())) - DateHelpers.localDateTimeToLong(DateHelpers.parseDateTime(o1.getCreateTime()))));
        System.out.println("fileNameList === " + fileNameList);
        return PageUtils.getPage(page.getCurrent(), page.getSize(), logResPage, fileNameList);
    }

    /**
     * 日志详情
     */
    public IPage<String> appLogDetail(Page<String> page, String appName, String fileName) {
        String path = filePath;
        if (DataHelpers.isNotEmptyString(appName)) {
            path = path + File.separator + appName;
        } else {
            throw new GeneralException("应用名为空");
        }
        if (DataHelpers.isNotEmptyString(fileName)) {
            path = path + File.separator + fileName;
        } else {
            throw new GeneralException("文件名为空");
        }
        List<String> list = FileUtil.readFileUtil(path);
        Page<String> p = new Page<>();
        return PageUtils.getPage(page.getCurrent(), page.getSize(), p, list);
    }

    /**
     * 行为统计
     */
    public List<Map<String, String>> behaviorStatistics() {
        return baseMapper.behaviorStatistics();
    }

    /**
     * 访问数量
     */
    public List<Map<String, String>> numberVisits() {
        //默认统计今天
        return baseMapper.numberVisits(DateUtil.getDate());
    }

    /**
     * 用户及ip总数
     */
    public NumberVisitsRes userCount() {
        NumberVisitsRes numberVisitsRes = new NumberVisitsRes();
        Integer userCount = 0;
        Integer ipCount = 0;
        Integer pageCount = 0;
        Double avgCount = 0.0;
        //用户访问量
        Integer ucount = baseMapper.userCount();
        if (DataHelpers.isNotEmpty(ucount)) {
            userCount = ucount;
        }
        numberVisitsRes.setUserCount(userCount);

        //ip访问量
        Integer icount = baseMapper.ipCount();
        if (DataHelpers.isNotEmpty(icount)) {
            ipCount = icount;
        }
        numberVisitsRes.setIpCount(ipCount);

        //页面总数
        Integer pcount = baseMapper.pageCount();
        if (DataHelpers.isNotEmpty(pcount)) {
            pageCount = pcount;
        }
        numberVisitsRes.setPageCount(pageCount);

        //平均访问量
        QueryWrapper<PubUserActionLog> queryWrapper = new QueryWrapper();
        queryWrapper.like("gmt_create",DateUtil.getDate());
        Integer aCount = baseMapper.selectCount(queryWrapper);
        if (DataHelpers.isNotEmpty(aCount)) {
            Double aDouble = Double.valueOf(aCount);
            avgCount = sub(aDouble,24,2);
        }
        numberVisitsRes.setAvgCount(avgCount);
        return numberVisitsRes;
    }


    /**
     * 提供精确减法运算的sub方法
     * @param value1 被减数
     * @param value2 减数
     * @return 两个参数的差
     */
    public double sub(double value1,double value2,int scale){
        BigDecimal b1 = new BigDecimal(String.valueOf(value1));
        BigDecimal b2 = new BigDecimal(String.valueOf(value2));
        return b1.divide(b2,scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 应用类统计
     */
    public List<Map<String, Integer>> appCount() {
        return baseMapper.appCount();
    }
}